home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 8 / Revista CD Expert nº 08 CD1.iso / Utilitarios / Programacao / Pacific C for DOS / EXAMPLES / USAGE.C < prev   
C/C++ Source or Header  |  1995-03-08  |  6KB  |  244 lines

  1. #include    <stat.h>
  2. #include    <stdio.h>
  3. #include    <stdlib.h>
  4. #include    <string.h>
  5.  
  6. /*
  7.  *    USAGE.C        Colin Weaver, HI-TECH Software, 1992
  8.  *
  9.  *    MS-DOS file space/blocks usage utility.  Scans all files
  10.  *    in one or more directories and works out how many bytes
  11.  *    and allocation blocks of disk space have been used.
  12.  *
  13.  *    This utility can recursively scan directories, thereby
  14.  *    giving the entire space usage for a directory tree.
  15.  *
  16.  *    Usage [-Bblocksize] [-D] [-V] [-R] [files]
  17.  *
  18.  *        -Bblocksize    set disk block size (default 1024)
  19.  *        -D        account for space used by directories
  20.  *        -Q        quiet mode: don't list files or directories
  21.  *        -R        recursively scan directories (turns on -D)
  22.  *        -V        verbose: list files as they are scanned
  23.  *
  24.  *    Any other argument will be treated as a wildcard.
  25.  */
  26.  
  27. #ifndef    BOOL
  28. #define    BOOL    unsigned char
  29. #define    FALSE    0
  30. #define    TRUE    1
  31. #endif
  32.  
  33. /*
  34.  *    Parameters and settings.
  35.  */
  36.  
  37. #if    DOS
  38. #define    DIRSEP        '\\'
  39. #define    WILDCARD    "*.*"
  40. #else
  41. #define    DIRSEP        '/'
  42. #define    WILDCARD    "*"
  43. #endif
  44.  
  45. static char        dirsep[] = { DIRSEP, 0 };
  46.  
  47. static unsigned int    block_size = 1024;    /* size of a disk block */
  48. static BOOL        verbose = FALSE;    /* verbose mode ? */
  49. static BOOL        add_dirs = FALSE;    /* account for directories */
  50. static BOOL        recurse = FALSE;    /* recursive scan ? */
  51. static BOOL        quiet = FALSE;        /* quiet scan ? */
  52. static char        wildcard[1024];        /* current wildcard */
  53.  
  54. /*
  55.  *    Global totals
  56.  */
  57.  
  58. static unsigned long    total_size = 0;        /* total size in bytes */
  59. static unsigned long    total_blocks = 0;    /* total blocks */
  60. static unsigned long    total_files = 0;    /* total number of files */
  61. static unsigned int    total_dirs = 0;        /* number of dirs scanned */
  62.  
  63. /*
  64.  *    void    scan(void)
  65.  *
  66.  *    Scan a directory using the current wildcard.
  67.  */
  68.  
  69. static void
  70. scan(void)
  71. {
  72. static    struct dirbuf *    dir;            /* directory entry */
  73. static    unsigned int    files;
  74. static    unsigned long    file_size;        /* size of current file */
  75. static    unsigned long    file_blocks;        /* blocks in current file */
  76. static    unsigned long    dir_size;        /* current directory size */
  77. static    unsigned long    dir_blocks;        /* current directory blocks */
  78. static    unsigned int    s_namesize;
  79. static    unsigned int    s_bufsize;
  80.     char *        s_wcard;
  81.     char *        s_buf;
  82.     unsigned int    s_ofs;
  83.     unsigned int    s_count;
  84.  
  85.     dir_size = dir_blocks = 0;        /* zap directory totals */
  86.     files = 0;
  87.     dir = ffirst(wildcard);
  88.     if (!dir) {
  89.         if (!(quiet && recurse))
  90.             fprintf(stderr, "No files match %s\n", wildcard);
  91.         return;
  92.     }
  93.     if (!quiet) {
  94.         if (strlen(wildcard) <= 24) {
  95.             printf("%-24s: ", wildcard);
  96.             if (verbose)
  97.                 putchar('\n');
  98.             else
  99.                 fflush(stdout);
  100.         } else {
  101.             printf("%s:\n", wildcard);
  102.             if (!verbose) {
  103.                 printf("%26s", " ");
  104.                 fflush(stdout);
  105.             }
  106.         }
  107.     }
  108.     s_buf = NULL;
  109.     s_bufsize = s_count = s_ofs = 0;
  110.     for (; dir; dir = fnext()) {
  111.         if (dir->di_stat.st_mode & S_IFDIR) {     /* directory ? */
  112.             if (!add_dirs)
  113.                 continue;
  114.             if (dir->di_name[0] == '.' && (dir->di_name[1] == 0 || dir->di_name[1] == '.'))
  115.                 continue;
  116.             if (recurse) {
  117.                 s_namesize = strlen(dir->di_name) + 1;
  118.                 if ((s_ofs + s_namesize) > s_bufsize) {
  119.                     s_bufsize += 512;
  120.                     s_buf = realloc(s_buf, s_bufsize);
  121.                     if (!s_buf) {
  122.                         fprintf(stderr, "Abort: unable to allocate any more memory\n");
  123.                         exit(1);
  124.                     }
  125.                 }
  126.                 strcpy(s_buf + s_ofs, dir->di_name);
  127.                 s_ofs += s_namesize;
  128.                 ++s_count;
  129.             }
  130.         }
  131.         file_size = dir->di_stat.st_size;
  132.         file_blocks = (file_size + block_size - 1) / block_size;
  133.         dir_size += file_size;
  134.         dir_blocks += file_blocks;
  135.         ++files;
  136.         if (verbose && !quiet)
  137.             printf("%-12s | %8lu bytes | %5lu blocks%s\n",
  138.                 dir->di_name, file_size, file_blocks,
  139.                 (dir->di_stat.st_mode & S_IFDIR)? " <DIR>": "");
  140.     }
  141.     if (!quiet)
  142.         printf("Total: %8lu bytes, %5lu blocks, %d files\n",
  143.             dir_size, dir_blocks, files);
  144.     total_files += files;
  145.     total_size += dir_size;
  146.     total_blocks += dir_blocks;
  147.      ++total_dirs;
  148.     if (quiet) {
  149.         printf("%lu files, %lu blocks, %lu bytes\r",
  150.             total_files, total_blocks, total_size);
  151.         fflush(stdout);
  152.     }
  153.     if (recurse && s_count) {
  154.         if (s_wcard = strrchr(wildcard, DIRSEP))
  155.             ++s_wcard;
  156.         else
  157.             s_wcard = wildcard;
  158.         s_ofs = 0;
  159.         while (s_count--) {
  160.             strcat(strcat(strcpy(s_wcard, s_buf + s_ofs), dirsep), WILDCARD);
  161.             s_ofs += strlen(s_buf + s_ofs) + 1;
  162.             scan();
  163.         }
  164.         free(s_buf);
  165.     }
  166. }
  167.  
  168. /*
  169.  *    void    bad_arg(char * arg)
  170.  *
  171.  *    Complain about a bad argument.
  172.  */
  173.  
  174. static void
  175. bad_arg(char * arg)
  176. {
  177.     fprintf(stderr, "Bad argument ignored: \"%s\"\n", arg);
  178. }
  179.  
  180. /*
  181.  *    main(int argc, char ** argv)
  182.  *
  183.  *    Handle command line arguments
  184.  */
  185.  
  186. int
  187. main(int argc, char ** argv)
  188. {
  189.     unsigned int    bs;
  190.     BOOL        scan_done;
  191.  
  192.     scan_done = FALSE;
  193.     while (*++argv) {
  194.         if (argv[0][0] == '-') {
  195.             switch(argv[0][1]) {
  196.             case 'b':
  197.             case 'B':
  198.                 if (scan_done)
  199.                     fprintf(stderr, "Can't change block size now: a directory has already been scanned!\n");
  200.                 else if (sscanf(argv[0] + 2, "%d", &bs) != 1)
  201.                     bad_arg(argv[0]);
  202.                 else if (bs < 1)
  203.                     bad_arg(argv[0]);
  204.                 else
  205.                     block_size = bs;
  206.                 break;
  207.             case 'r':
  208.             case 'R':
  209.                 recurse = TRUE;
  210.             case 'd':
  211.             case 'D':
  212.                 add_dirs = TRUE;
  213.                 break;
  214.             case 'v':
  215.             case 'V':
  216.                 verbose = TRUE;
  217.                 break;
  218.             case 'q':
  219.             case 'Q':
  220.                 quiet = TRUE;
  221.                 break;
  222.             default:
  223.                 bad_arg(argv[0]);
  224.                 break;
  225.             }
  226.         } else {
  227.             scan_done = TRUE;
  228.             strcpy(wildcard, argv[0]);
  229.             scan();
  230.         }
  231.     }
  232.     if (!scan_done) {
  233.         strcpy(wildcard, WILDCARD);
  234.         scan();
  235.     }
  236.     if (total_dirs > 1 && !quiet) {
  237.         printf("%u directories scanned:\n", total_dirs);
  238.         printf("Total: %8lu bytes, %5lu blocks, %lu files\n",
  239.             total_size, total_blocks, total_files);
  240.     }
  241.     if (quiet)
  242.         putchar('\n');
  243. }
  244.